use windows::{
    core::{Result, PCWSTR},
    Win32::{
        Foundation::{CloseServiceHandle, GetLastError, HANDLE},
        Security::{GetTokenInformation, TokenElevation, TOKEN_ELEVATION, TOKEN_QUERY},
        System::{
            Services::{
                ControlService, OpenSCManagerW, OpenServiceW, QueryServiceStatus, StartServiceW,
                SERVICE_CONTROL_STOP, SERVICE_QUERY_STATUS, SERVICE_START, SERVICE_STATUS,
                SC_MANAGER_ALL_ACCESS, SERVICE_STOP,
            },
            Threading::{GetCurrentProcess, OpenProcessToken},
        },
        UI::Shell::{ShellExecuteW, SHELLEXECUTEINFOW, SEE_MASK_NOCLOSEPROCESS, SW_SHOW},
    },
};

fn main() -> Result<()> {
    if !is_running_as_admin()? {
        println!("当前用户没有管理员权限，尝试提升权限...");
        run_as_admin()?;
        return Ok(());
    }

    let service_name = "YourServiceName";

    unsafe {
        let scm_handle = OpenSCManagerW(None, None, SC_MANAGER_ALL_ACCESS);
        if scm_handle.is_invalid() {
            eprintln!("无法打开服务控制管理器: {:?}", GetLastError());
            return Ok(());
        }

        let service_handle = OpenServiceW(
            scm_handle,
            PCWSTR(service_name.encode_utf16().collect::<Vec<u16>>().as_ptr()),
            SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS,
        );

        if service_handle.is_invalid() {
            eprintln!("无法打开服务: {} 错误: {:?}", service_name, GetLastError());
            CloseServiceHandle(scm_handle);
            return Ok(());
        }

        if !StartServiceW(service_handle, &[]) {
            eprintln!("无法启动服务: {} 错误: {:?}", service_name, GetLastError());
        } else {
            println!("服务已启动: {}", service_name);
        }

        let mut service_status: SERVICE_STATUS = std::mem::zeroed();
        if !QueryServiceStatus(service_handle, &mut service_status) {
            eprintln!("无法查询服务状态: {} 错误: {:?}", service_name, GetLastError());
        } else {
            println!("服务当前状态: {}", service_status.dwCurrentState);
        }

        if !ControlService(service_handle, SERVICE_CONTROL_STOP, &mut service_status) {
            eprintln!("无法停止服务: {} 错误: {:?}", service_name, GetLastError());
        } else {
            println!("服务已停止: {}", service_name);
        }

        CloseServiceHandle(service_handle);
        CloseServiceHandle(scm_handle);
    }

    Ok(())
}

fn is_running_as_admin() -> Result<bool> {
    unsafe {
        let mut token_handle: HANDLE = HANDLE::default();
        if !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token_handle).as_bool() {
            return Err(GetLastError().into());
        }

        let mut elevation = TOKEN_ELEVATION::default();
        let mut return_length = 0;
        let result = GetTokenInformation(
            token_handle,
            TokenElevation,
            &mut elevation as *mut _ as *mut _,
            std::mem::size_of::<TOKEN_ELEVATION>() as u32,
            &mut return_length,
        );

        CloseServiceHandle(token_handle);

        if !result.as_bool() {
            return Err(GetLastError().into());
        }

        Ok(elevation.TokenIsElevated != 0)
    }
}

fn run_as_admin() -> Result<()> {
    let exe_path = std::env::current_exe()?;
    let exe_path_str = exe_path.to_str().unwrap();

    let params = SHELLEXECUTEINFOW {
        cbSize: std::mem::size_of::<SHELLEXECUTEINFOW>() as u32,
        fMask: SEE_MASK_NOCLOSEPROCESS,
        hwnd: None,
        lpVerb: PCWSTR("runas\0".encode_utf16().collect::<Vec<u16>>().as_ptr()),
        lpFile: PCWSTR(exe_path_str.encode_utf16().collect::<Vec<u16>>().as_ptr()),
        lpParameters: PCWSTR::null(),
        lpDirectory: PCWSTR::null(),
        nShow: SW_SHOW,
        hInstApp: None,
        ..Default::default()
    };

    unsafe {
        if ShellExecuteW(&params).0 <= 32 {
            eprintln!("无法提升权限");
            return Err(GetLastError().into());
        }
    }

    Ok(())
}
